package com.zr.spring.jedis;

import com.google.gson.Gson;
import redis.clients.jedis.*;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RedisJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("192.168.1.2");
        // 如果 Redis 服务设置了密码，需要下面这行，没有就不需要
        jedis.auth("jszc@1234");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: " + jedis.ping());

//        new RedisJava().redisString(jedis);
//        new RedisJava().redisHash(jedis);
//
//        new RedisJava().redisList(jedis);
//        new RedisJava().redisSet(jedis);
//        new RedisJava().redisZSet(jedis);
//        new RedisJava().redisGeog(jedis);
        new RedisJava().redisHash(jedis);
    }


    public void redisString(Jedis jedis) {
        String key = "key6";
        String value = "value6";
        if (jedis.exists(key)) jedis.del(key);
        jedis.set(key, value);
        System.out.println("key:" + key + "---value:" + jedis.get(key));
    }

    public void redisHash(Jedis jedis) {
        String key = "hk";

        HashMap<String, String> map = new HashMap<>();
        for (int i = 0; i < 10; i++) {
            Person person = new Person("zhangrui" + i, "1" + i, "男");
            map.put(person.getName(),new Gson().toJson(person));
        }
        if (jedis.exists(key)) jedis.del(key);

        //单个插入
        jedis.hmset(key, map);
        String result = new Gson().toJson(jedis.hgetAll(key));

        System.out.println("hash value is:" + result);
    }

    public void redisList(Jedis jedis) {
        String key = "kl";
        if (jedis.exists(key)) jedis.del(key);
        jedis.lpush(key, "redis", "mongodb", "rabbitmq", "mysql");
        System.out.println("list value is :" + new Gson().toJson(jedis.lrange(key, 0, 10)));
    }

    public void redisSet(Jedis jedis) {
        String key = "ks";
        if (jedis.exists(key)) {
            jedis.del(key);
        }
        jedis.sadd(key, "redis", "rabbitmq", "mysql", "mongodb");
        System.out.println("set value is:" + new Gson().toJson(jedis.smembers(key)));
    }

    public void redisZSet(Jedis jedis) {
        String key = "kzs";
        if (jedis.exists(key)) jedis.del(key);
        HashMap<String, Double> map = new HashMap<>();
        map.put("redis", 0.0);
        map.put("mongodb", 1.0);
        map.put("mysql", 2.0);
        map.put("rabbitmq", 4.0);
        map.put("kafka", 3.0);
        jedis.zadd(key, map);
        System.out.println("zset value is:" + new Gson().toJson(jedis.zrange(key, 0, 10)));
    }

    public void redisGeog(Jedis jedis) {
        String key = "cities";
        if (jedis.exists(key)) jedis.del(key);
        jedis.geoadd(key, 125.19, 43.54, "changchun");
        jedis.geoadd(key, 116.23128, 40.22077, "beijing");
        jedis.geoadd(key, 108.93425, 34.23053, "xian");
        jedis.geoadd(key, 103.71878, 36.10396, "lanzhou");
        jedis.geoadd(key, 121.48941, 31.40527, "shanghai");
        jedis.geoadd(key, 120.39629, 36.30744, "qingdao");
        jedis.geoadd(key, 121.5255, 38.95223, "dalian");
        jedis.geoadd(key, 113.6401, 34.72468, "qingdao");

        //两个地点之间的距离
        Double BeijingToXian = jedis.geodist(key, "xian", "beijing", GeoUnit.KM);
        System.out.println(BeijingToXian);
        //基于经纬度坐标的范围查询
        List<GeoRadiusResponse> geoRadius = jedis.georadius(key, 129.30, 42, 1000, GeoUnit.KM);
        System.out.println(new Gson().toJson(geoRadius));

        //基于成员位置范围的查询
        List<GeoRadiusResponse> memberDis = jedis.georadiusByMember(key, "beijing", 1000, GeoUnit.KM);
        System.out.println(new Gson().toJson(memberDis));

        //获取成员经纬度
        List<GeoCoordinate> beijingPos = jedis.geopos(key, "beijing");
        System.out.println(new Gson().toJson(beijingPos));
    }

    public void redisHyperLog(Jedis jedis) {
        String key1 = "kpf1";
        String key2 = "kpf2";
        jedis.pfadd(key1, "a", "b", "c", "d", "e", "f", "g", "a");
        jedis.pfadd(key2, "ab", "bd", "c", "d", "e", "f", "g", "a");
        long count = jedis.pfcount(key1);
        System.out.println(count);
        String merge = jedis.pfmerge(key1, key2);
        System.out.println(merge);
    }

    /**
     * BitMap 都是操作二进制来进行记录
     */
    public void redisBitmap(Jedis jedis) {
        String key = "kBitmap";
        jedis.setbit(key, 1, true);
        jedis.setbit(key, 2, false);
        jedis.setbit(key, 3, true);
        jedis.setbit(key, 4, false);
        jedis.setbit(key, 5, true);
        jedis.setbit(key, 6, false);
        jedis.setbit(key, 6, true);
        Long count = jedis.bitcount(key);
        System.out.println(count);
    }

    /**
     * redis 乐观锁的实现
     *
     * @param jedis
     */
    public void redisOptLock(Jedis jedis) {
        String redisKey = "redisTest";
        jedis.set(redisKey, "0");
        ExecutorService executorService = Executors.newFixedThreadPool(20);


        for (int i = 0; i < 10000; i++) {
            executorService.execute(() -> {
                Jedis jedis1 = new Jedis("47.107.221.219", 6379);
                try {
                    jedis1.watch(redisKey);
                    String redisValue = jedis1.get(redisKey);
                    int valInteger = Integer.valueOf(redisValue);
                    String userInfo = UUID.randomUUID().toString();
                    if (valInteger < 20) {
                        Transaction transaction = jedis1.multi();
                        transaction.incr(redisKey);
                        List list = transaction.exec();
                        if (list != null) {
                            System.out.println("用户：" + userInfo + "，秒杀成功！当前成功人数：" + (valInteger + 1));
                        } else {
                            System.out.println("用户：" + userInfo + "，秒杀失败");
                        }
                    } else {
                        System.out.println("已经有20人秒杀成功，秒杀结束");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    jedis1.close();
                }
            });
        }
        executorService.shutdown();
    }
}
